package com.qimu.saiyou.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qimu.saiyou.common.ErrorCode;
import com.qimu.saiyou.exception.BusinessException;
import com.qimu.saiyou.mapper.FriendsApplyMapper;
import com.qimu.saiyou.model.dto.friendsapply.FriendApplyRequest;
import com.qimu.saiyou.model.entity.Friends;
import com.qimu.saiyou.model.entity.FriendsApply;
import com.qimu.saiyou.model.entity.User;
import com.qimu.saiyou.model.enums.FriendApplyStatusEnum;
import com.qimu.saiyou.service.FriendsApplyService;
import com.qimu.saiyou.service.FriendsService;
import com.qimu.saiyou.service.UserService;
import com.qimu.saiyou.utils.RedissonLockUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;

/**
 * @author: FeiXiang
 * @description 针对表【friends_apply(好友申请表)】的数据库操作Service实现
 * @createDate 2024-04-19 20:49:35
 */
@Service
public class FriendsApplyServiceImpl extends ServiceImpl<FriendsApplyMapper, FriendsApply>
        implements FriendsApplyService {
    @Resource
    private RedissonLockUtil redissonLockUtil;
    @Resource
    private UserService userService;
    @Resource
    private FriendsService friendsService;

    @Override
    public boolean applyFriend(User loginUser, FriendApplyRequest friendApplyRequest) {
        if (StringUtils.isNotBlank(friendApplyRequest.getRemark()) && friendApplyRequest.getRemark().length() > 120) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "申请备注最多120个字符");
        }
        if (ObjectUtils.anyNull(loginUser.getId(), friendApplyRequest.getReceiveId()) || friendApplyRequest.getReceiveId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 1.添加的不能是自己
        if (loginUser.getId().equals(friendApplyRequest.getReceiveId())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "不能添加自己为好友");
        }
        User userServiceById = userService.getById(friendApplyRequest.getReceiveId());
        if (userServiceById == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在");
        }
        return redissonLockUtil.redissonDistributedLocks("applyFriend:" + loginUser.getId(), () -> {
            Long applyCount = this.lambdaQuery()
                    .eq(FriendsApply::getFromId, loginUser.getId())
                    .eq(FriendsApply::getStatus, 0)
                    .eq(FriendsApply::getReceiveId, friendApplyRequest.getReceiveId())
                    .count();
            if (applyCount > 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "对方还未同意，请耐心等待哦~");
            }
            FriendsApply friendsApply = new FriendsApply();
            friendsApply.setFromId(loginUser.getId());
            friendsApply.setReceiveId(userServiceById.getId());
            if (StringUtils.isBlank(friendApplyRequest.getRemark())) {
                friendsApply.setRemark("我是" + (StringUtils.isNotBlank(loginUser.getUserName()) ? loginUser.getUserName() : loginUser.getUserAccount()));
            } else {
                friendsApply.setRemark(friendApplyRequest.getRemark());
            }
            return this.save(friendsApply);
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean agreedFriend(User loginUser, long id) {
        FriendsApply friendsApply = this.getById(id);
        if (friendsApply == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "申请不存在");
        }
        if (!friendsApply.getReceiveId().equals(loginUser.getId())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }

        return redissonLockUtil.redissonDistributedLocks("agreedFriend:" + loginUser.getId(), () -> {
            Integer status = friendsApply.getStatus();
            if (status.equals(FriendApplyStatusEnum.AGREE_STATUS.getValue())) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "已经同意过了");
            }
            if (DateUtil.between(new Date(), friendsApply.getCreateTime(), DateUnit.DAY) >= 3 || status.equals(FriendApplyStatusEnum.EXPIRED_STATUS.getValue())) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "该申请已过期");
            }
            if (status.equals(FriendApplyStatusEnum.REVOKE_STATUS.getValue())) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "已撤销");
            }

            Friends friends = new Friends();
            friends.setReceiveId(friendsApply.getFromId());
            friends.setUserId(loginUser.getId());

            Friends friend = new Friends();
            friend.setReceiveId(loginUser.getId());
            friend.setUserId(friendsApply.getFromId());
            friendsService.saveBatch(Arrays.asList(friends, friend));
            friendsApply.setStatus(1);
            return this.updateById(friendsApply);
        });
    }

    /**
     * 被拒绝朋友
     *
     * @param loginUser 登录用户
     * @param id        身份证件
     * @return boolean
     */
    @Override
    public boolean refusedFriend(User loginUser, long id) {
        FriendsApply friendsApply = this.getById(id);
        if (friendsApply == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "申请不存在");
        }
        if (!friendsApply.getReceiveId().equals(loginUser.getId())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        friendsApply.setStatus(FriendApplyStatusEnum.REFUSED_STATUS.getValue());
        return this.updateById(friendsApply);
    }

    /**
     * 撤销好友
     *
     * @param loginUser 登录用户
     * @param id        身份证件
     * @return boolean
     */
    @Override
    public boolean revokeFriend(User loginUser, long id) {
        FriendsApply friendsApply = this.getById(id);
        if (friendsApply == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "申请不存在");
        }
        if (!friendsApply.getFromId().equals(loginUser.getId())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        friendsApply.setStatus(FriendApplyStatusEnum.REVOKE_STATUS.getValue());
        return this.updateById(friendsApply);
    }
}




